Skip to main content

Speaker gRPC service

Speaker Service

  • add the repositories middleware
Repositories middleware

builder.Services.AddRepositories();

  • add a .proto file name speakers.proto
Speaker proto
Title

syntax = "proto3";

option csharp_namespace = "Speaker.Service.Protos";
package speakers;

service SpeakerServiceDefinition{

rpc GetById (SpeakerFilterRequest) returns (SpeakerResponse) {}
rpc Create (SpeakerCreateRequest) returns (SpeakerResponse) {}
rpc Update (SpeakerUpdateRequest) returns (google.protobuf.Empty) {}
rpc Delete (SpeakerFilterRequest) returns (google.protobuf.Empty) {}

}

message SpeakerFilterRequest {
int32 Id = 1;
}

message SpeakerUpdateRequest {
int32 Id = 1;
string FirstName = 2;
string LastName = 3;
string Bio = 4;
string Country = 5;
string Website = 6;
string Email = 7;
string City = 8;
}

message SpeakerResponse {
int32 Id = 1;
string FirstName = 2;
string LastName = 3;
string Bio = 4;
string Country = 5;
string Website = 6;
string Email = 7;
string City = 8;
}

message SpeakerCreateRequest {
string FirstName = 2;
string LastName = 3;
string Bio = 4;
string Country = 5;
string Website = 6;
string Email = 7;
string City = 8;
}

  • add the SpeakerService.cs
SpeakerService.cs

public override Task<SpeakerResponse> GetById(SpeakerFilterRequest request, ServerCallContext context)
{

var speaker = speakerRepository.GetByIdAsync(request.Id);

if (speaker.Result == null)
throw new RpcException(new Status(StatusCode.NotFound, $"Speaker with Id {request.Id} doesn't exist!"));

var speakerResponse = mapper.Map<SpeakerResponse>(speaker.Result);
return Task.FromResult(speakerResponse);

}

public override async Task<SpeakersResponse> GetAllAtOnce(Empty request, ServerCallContext context)
{
var speakers = await speakerRepository.GetAllAsync();
var speakersResponse = new SpeakersResponse() { };

var speakersAll = mapper.Map<List<SpeakerResponse>>(speakers);
speakersResponse.Speakers.AddRange(speakersAll);
return speakersResponse;
}

public override async Task GetAll(Empty request, IServerStreamWriter<SpeakerResponse> responseStream, ServerCallContext context)
{
var speakers = await speakerRepository.GetAllAsync();

foreach (var speaker in speakers)
{
var speakerResponse = mapper.Map<SpeakerResponse>(speaker);
await responseStream.WriteAsync(speakerResponse);
}
await Task.CompletedTask;
}

public override async Task<Empty> Update(SpeakerUpdateRequest request, ServerCallContext context)
{
var speakerToUpdate = mapper.Map<Domain.Speaker>(request);

var updateSucceed = await speakerRepository.UpdateAsync(speakerToUpdate);

if (updateSucceed <= 0)
throw new RpcException(new Status(StatusCode.NotFound, $"Speaker with Id {request.Id} hasn't been updated"));

return new Empty();
}

public override async Task<Empty> Delete(SpeakerFilterRequest request, ServerCallContext context)
{
var deleteSucceed = await speakerRepository.DeleteAsync(request.Id);

if (deleteSucceed <= 0)
throw new RpcException(new Status(StatusCode.NotFound, $"Speaker with Id {request.Id} hasn't been deleted."));

return new Empty();
}


  • register the SpeakerService in the Program.cs - app.MapGrpcService<SpeakerService>();
  • install AutoMapper
  • add a folder named Mappings
  • add a class named SpeakerMappingProfile, that will contain the mapping classes
Title
 public class SpeakerMappingProfile : Profile
{
public SpeakerMappingProfile()
{
CreateMap<Domain.Speaker, SpeakerResponse>();
CreateMap<SpeakerCreateRequest, Domain.Speaker>();
CreateMap<SpeakerUpdateRequest, Domain.Speaker>();

CreateMap<List<Domain.Speaker>, SpeakersResponse>();
}
}
  • go to Program.cs
Register automapper
builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
builder.Services.AddAutoMapper(typeof(SpeakerMappingProfile));